package cn.pink.gatesrv;

import cn.pink.common.support.tools.cache.CacheTool;
import cn.pink.common.support.tools.cache.ICacheListener;
import cn.pink.common.support.tools.cache.RemoveReason;
import cn.pink.core.NodeType;
import cn.pink.core.Port;
import cn.pink.core.Service;
import cn.pink.core.Session;
import cn.pink.core.config.CacheConfig;
import cn.pink.core.gen.proxy.DistrClass;
import cn.pink.core.gen.proxy.DistrMethod;
import cn.pink.core.support.Log;
import cn.pink.core.support.Param;

/**
 * @Author: pink
 * @Date: 2022/6/21 16:53
 */
@DistrClass(nodeType = NodeType.GATE)
public class GateService extends Service {
    public GateService(Port port) {
        super(port);

        CacheTool.getInstance().registerListener(CacheConfig.SESSION, new ICacheListener() {
            @Override
            public void elementAdd(String key, Object value) {
//                Log.gate.info("session put: key={}, value={}", key, value);
            }

            @Override
            public void elementUpdate(String key, Object value, Object oldValue) {
//                Log.gate.info("session update: key={}, value={}, oldValue={}", key, value, oldValue);

                //玩家断线重连, 立即断开旧连接
                //2种情况会执行elementUpdate
                //1.玩家wifi,4g互切导致断线重连
                //2.玩家正常下线, 在离线保护时间内再次上线

                Session session = (Session) value;
                Session oldSession = (Session) oldValue;

                SessionService oldService = port.getService(oldSession.getId());
                if(oldService == null) {
                    return;
                }

                oldService.closeImmediate();

                Log.gate.info("human reLogin: humanId={}, oldSession={}, newSession={}", key, oldSession.getId(), session.getId());
            }

            @Override
            public void elementRemove(String key, Object oldValue, RemoveReason reason) {
//                Log.gate.info("session remove: key={}, oldValue={}, reason={}", key, oldValue, reason);

                //如果分布式部署某个game服宕机, 将其上的玩家下线, 从session池中移除, 走该回调关闭玩家所在gate上的连接
                //如果集群部署game宕了, 所在的gate必然也宕了. 其他cluster的gate也会走

                Session oldSession = (Session) oldValue;

                SessionService oldService = port.getService(oldSession.getId());
                if(oldService == null) {
                    return;
                }

                oldService.closeImmediate();

                Log.gate.info("human offline, because game node remove: humanId={}, oldSession={}", key, oldSession.getId());
            }
        });
    }

    @Override
    public Object getId() {
        return RPCProxy.GateServiceProxy.DIST_NAME;
    }

    @DistrMethod
    public Param defaultHandler(String str) {
        return null;
    }
}
